home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / linux / tools / gtar10.lha / getdate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-09  |  43.9 KB  |  1,775 lines

  1.  
  2. /*  A Bison parser, made from getdate.y  */
  3.  
  4. #define YYBISON 1  /* Identify Bison output.  */
  5.  
  6. #define    tAGO    258
  7. #define    tDAY    259
  8. #define    tDAYZONE    260
  9. #define    tID    261
  10. #define    tMERIDIAN    262
  11. #define    tMINUTE_UNIT    263
  12. #define    tMONTH    264
  13. #define    tMONTH_UNIT    265
  14. #define    tSEC_UNIT    266
  15. #define    tSNUMBER    267
  16. #define    tUNUMBER    268
  17. #define    tZONE    269
  18.  
  19. #line 1 "getdate.y"
  20.  
  21. /* $Revision: 2.1 $
  22. **
  23. **  Originally written by Steven M. Bellovin <smb@research.att.com> while
  24. **  at the University of North Carolina at Chapel Hill.  Later tweaked by
  25. **  a couple of people on Usenet.  Completely overhauled by Rich $alz
  26. **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
  27. **  send any email to Rich.
  28. **
  29. **  This grammar has eight shift/reduce conflicts.
  30. **
  31. **  This code is in the public domain and has no copyright.
  32. */
  33. /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
  34. /* SUPPRESS 288 on yyerrlab *//* Label unused */
  35.  
  36. #ifdef __GNUC__
  37. #define alloca __builtin_alloca
  38. #else
  39. #ifdef sparc
  40. #include <alloca.h>
  41. #else
  42. #ifdef _AIX /* for Bison */
  43. #pragma alloca
  44. #else
  45. char *alloca ();
  46. #endif
  47. #endif
  48. #endif
  49.  
  50. #include <stdio.h>
  51. #include <ctype.h>
  52.  
  53. #if    defined(vms)
  54. #include <types.h>
  55. #include <time.h>
  56. #else
  57. #include <sys/types.h>
  58. #if    defined(USG)
  59. /*
  60. **  Uncomment the next line if you need to do a tzset() call to set the
  61. **  timezone, and don't have ftime().  Some SystemV releases, I think.
  62. */
  63. /*#define NEED_TZSET */
  64. struct timeb {
  65.     time_t        time;        /* Seconds since the epoch    */
  66.     unsigned short    millitm;    /* Field not used        */
  67.     short        timezone;
  68.     short        dstflag;    /* Field not used        */
  69. };
  70. #else
  71. #include <sys/timeb.h>
  72. #endif    /* defined(USG) */
  73. #if    defined(BSD4_2) || defined(BSD4_1C)
  74. #include <sys/time.h>
  75. #else
  76. #include <time.h>
  77. #endif    /* defined(BSD4_2) */
  78. #endif    /* defined(vms) */
  79.  
  80. #if defined (STDC_HEADERS) || defined (USG)
  81. #include <string.h>
  82. #endif
  83.  
  84. extern struct tm    *localtime();
  85.  
  86. #define yyparse getdate_yyparse
  87. #define yylex getdate_yylex
  88. #define yyerror getdate_yyerror
  89.  
  90. #if    !defined(lint) && !defined(SABER)
  91. static char RCS[] =
  92.     "$Header: str2date.y,v 2.1 90/09/06 08:15:06 cronan Exp $";
  93. #endif    /* !defined(lint) && !defined(SABER) */
  94.  
  95.  
  96. #define EPOCH        1970
  97. #define HOUR(x)        (x * 60)
  98. #define SECSPERDAY    (24L * 60L * 60L)
  99.  
  100.  
  101. /*
  102. **  An entry in the lexical lookup table.
  103. */
  104. typedef struct _TABLE {
  105.     char    *name;
  106.     int        type;
  107.     time_t    value;
  108. } TABLE;
  109.  
  110.  
  111. /*
  112. **  Daylight-savings mode:  on, off, or not yet known.
  113. */
  114. typedef enum _DSTMODE {
  115.     DSTon, DSToff, DSTmaybe
  116. } DSTMODE;
  117.  
  118. /*
  119. **  Meridian:  am, pm, or 24-hour style.
  120. */
  121. typedef enum _MERIDIAN {
  122.     MERam, MERpm, MER24
  123. } MERIDIAN;
  124.  
  125.  
  126. /*
  127. **  Global variables.  We could get rid of most of these by using a good
  128. **  union as the yacc stack.  (This routine was originally written before
  129. **  yacc had the %union construct.)  Maybe someday; right now we only use
  130. **  the %union very rarely.
  131. */
  132. static char    *yyInput;
  133. static DSTMODE    yyDSTmode;
  134. static time_t    yyDayOrdinal;
  135. static time_t    yyDayNumber;
  136. static int    yyHaveDate;
  137. static int    yyHaveDay;
  138. static int    yyHaveRel;
  139. static int    yyHaveTime;
  140. static int    yyHaveZone;
  141. static time_t    yyTimezone;
  142. static time_t    yyDay;
  143. static time_t    yyHour;
  144. static time_t    yyMinutes;
  145. static time_t    yyMonth;
  146. static time_t    yySeconds;
  147. static time_t    yyYear;
  148. static MERIDIAN    yyMeridian;
  149. static time_t    yyRelMonth;
  150. static time_t    yyRelSeconds;
  151.  
  152.  
  153. #line 135 "getdate.y"
  154. typedef union {
  155.     time_t        Number;
  156.     enum _MERIDIAN    Meridian;
  157. } YYSTYPE;
  158.  
  159. #ifndef YYLTYPE
  160. typedef
  161.   struct yyltype
  162.     {
  163.       int timestamp;
  164.       int first_line;
  165.       int first_column;
  166.       int last_line;
  167.       int last_column;
  168.       char *text;
  169.    }
  170.   yyltype;
  171.  
  172. #define YYLTYPE yyltype
  173. #endif
  174.  
  175. #include <stdio.h>
  176.  
  177. #ifndef __STDC__
  178. #define const
  179. #endif
  180.  
  181.  
  182.  
  183. #define    YYFINAL        48
  184. #define    YYFLAG        -32768
  185. #define    YYNTBASE    18
  186.  
  187. #define YYTRANSLATE(x) ((unsigned)(x) <= 269 ? yytranslate[x] : 28)
  188.  
  189. static const char yytranslate[] = {     0,
  190.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  191.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  192.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  193.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  194.      2,     2,     2,    16,     2,     2,    17,     2,     2,     2,
  195.      2,     2,     2,     2,     2,     2,     2,    15,     2,     2,
  196.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  197.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  198.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  199.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  200.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  201.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  202.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  203.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  204.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  205.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  206.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  207.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  208.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  209.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  210.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  211.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  212.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  213.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  214.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  215.      2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
  216.      6,     7,     8,     9,    10,    11,    12,    13,    14
  217. };
  218.  
  219. #if YYDEBUG != 0
  220. static const short yyprhs[] = {     0,
  221.      0,     1,     4,     6,     8,    10,    12,    14,    16,    19,
  222.     24,    29,    36,    43,    45,    47,    49,    52,    55,    59,
  223.     65,    68,    73,    76,    80,    83,    85,    88,    91,    93,
  224.     96,    99,   101,   104,   107,   109,   111,   112
  225. };
  226.  
  227. #endif
  228.  
  229. static const short yyrhs[] = {    -1,
  230.     18,    19,     0,    20,     0,    21,     0,    23,     0,    22,
  231.      0,    24,     0,    26,     0,    13,     7,     0,    13,    15,
  232.     13,    27,     0,    13,    15,    13,    12,     0,    13,    15,
  233.     13,    15,    13,    27,     0,    13,    15,    13,    15,    13,
  234.     12,     0,    14,     0,     5,     0,     4,     0,     4,    16,
  235.      0,    13,     4,     0,    13,    17,    13,     0,    13,    17,
  236.     13,    17,    13,     0,     9,    13,     0,     9,    13,    16,
  237.     13,     0,    13,     9,     0,    13,     9,    13,     0,    25,
  238.      3,     0,    25,     0,    13,     8,     0,    12,     8,     0,
  239.      8,     0,    12,    11,     0,    13,    11,     0,    11,     0,
  240.     12,    10,     0,    13,    10,     0,    10,     0,    13,     0,
  241.      0,     7,     0
  242. };
  243.  
  244. #if YYDEBUG != 0
  245. static const short yyrline[] = { 0,
  246.    149,   150,   153,   156,   159,   162,   165,   168,   171,   177,
  247.    183,   190,   196,   206,   210,   216,   220,   224,   230,   234,
  248.    239,   243,   248,   252,   259,   263,   266,   269,   272,   275,
  249.    278,   281,   284,   287,   290,   295,   323,   326
  250. };
  251.  
  252. static const char * const yytname[] = {   "$","error","$illegal.","tAGO","tDAY",
  253. "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
  254. "tSNUMBER","tUNUMBER","tZONE","':'","','","'/'","spec","item","time","zone",
  255. "day","date","rel","relunit","number","o_merid",""
  256. };
  257. #endif
  258.  
  259. static const short yyr1[] = {     0,
  260.     18,    18,    19,    19,    19,    19,    19,    19,    20,    20,
  261.     20,    20,    20,    21,    21,    22,    22,    22,    23,    23,
  262.     23,    23,    23,    23,    24,    24,    25,    25,    25,    25,
  263.     25,    25,    25,    25,    25,    26,    27,    27
  264. };
  265.  
  266. static const short yyr2[] = {     0,
  267.      0,     2,     1,     1,     1,     1,     1,     1,     2,     4,
  268.      4,     6,     6,     1,     1,     1,     2,     2,     3,     5,
  269.      2,     4,     2,     3,     2,     1,     2,     2,     1,     2,
  270.      2,     1,     2,     2,     1,     1,     0,     1
  271. };
  272.  
  273. static const short yydefact[] = {     1,
  274.      0,    16,    15,    29,     0,    35,    32,     0,    36,    14,
  275.      2,     3,     4,     6,     5,     7,    26,     8,    17,    21,
  276.     28,    33,    30,    18,     9,    27,    23,    34,    31,     0,
  277.      0,    25,     0,    24,    37,    19,    22,    38,    11,     0,
  278.     10,     0,    37,    20,    13,    12,     0,     0
  279. };
  280.  
  281. static const short yydefgoto[] = {     1,
  282.     11,    12,    13,    14,    15,    16,    17,    18,    41
  283. };
  284.  
  285. static const short yypact[] = {-32768,
  286.      0,   -14,-32768,-32768,   -10,-32768,-32768,    23,    11,-32768,
  287. -32768,-32768,-32768,-32768,-32768,-32768,     4,-32768,-32768,     1,
  288. -32768,-32768,-32768,-32768,-32768,-32768,     3,-32768,-32768,    10,
  289.     12,-32768,    14,-32768,    17,    13,-32768,-32768,-32768,    22,
  290. -32768,    24,    -6,-32768,-32768,-32768,    36,-32768
  291. };
  292.  
  293. static const short yypgoto[] = {-32768,
  294. -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    -5
  295. };
  296.  
  297.  
  298. #define    YYLAST        38
  299.  
  300.  
  301. static const short yytable[] = {    47,
  302.     38,    19,    20,     2,     3,    45,    32,     4,     5,     6,
  303.      7,     8,     9,    10,    24,    34,    33,    25,    26,    27,
  304.     28,    29,    35,    38,    36,    30,    37,    31,    39,    42,
  305.     21,    40,    22,    23,    43,    48,    44,    46
  306. };
  307.  
  308. static const short yycheck[] = {     0,
  309.      7,    16,    13,     4,     5,    12,     3,     8,     9,    10,
  310.     11,    12,    13,    14,     4,    13,    16,     7,     8,     9,
  311.     10,    11,    13,     7,    13,    15,    13,    17,    12,    17,
  312.      8,    15,    10,    11,    13,     0,    13,    43
  313. };
  314. /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
  315. #line 3 "/usr/local/lib/bison.simple"
  316.  
  317. /* Skeleton output parser for bison,
  318.    Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
  319.  
  320.    This program is free software; you can redistribute it and/or modify
  321.    it under the terms of the GNU General Public License as published by
  322.    the Free Software Foundation; either version 1, or (at your option)
  323.    any later version.
  324.  
  325.    This program is distributed in the hope that it will be useful,
  326.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  327.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  328.    GNU General Public License for more details.
  329.  
  330.    You should have received a copy of the GNU General Public License
  331.    along with this program; if not, write to the Free Software
  332.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  333.  
  334.  
  335. #ifndef alloca
  336. #ifdef __GNUC__
  337. #define alloca __builtin_alloca
  338. #else /* not GNU C.  */
  339. #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
  340. #include <alloca.h>
  341. #else /* not sparc */
  342. #if defined (MSDOS) && !defined (__TURBOC__)
  343. #include <malloc.h>
  344. #else /* not MSDOS, or __TURBOC__ */
  345. #if defined(_AIX)
  346. #include <malloc.h>
  347.  #pragma alloca
  348. #endif /* not _AIX */
  349. #endif /* not MSDOS, or __TURBOC__ */
  350. #endif /* not sparc.  */
  351. #endif /* not GNU C.  */
  352. #endif /* alloca not defined.  */
  353.  
  354. /* This is the parser code that is written into each bison parser
  355.   when the %semantic_parser declaration is not specified in the grammar.
  356.   It was written by Richard Stallman by simplifying the hairy parser
  357.   used when %semantic_parser is specified.  */
  358.  
  359. /* Note: there must be only one dollar sign in this file.
  360.    It is replaced by the list of actions, each action
  361.    as one case of the switch.  */
  362.  
  363. #define yyerrok        (yyerrstatus = 0)
  364. #define yyclearin    (yychar = YYEMPTY)
  365. #define YYEMPTY        -2
  366. #define YYEOF        0
  367. #define YYACCEPT    return(0)
  368. #define YYABORT     return(1)
  369. #define YYERROR        goto yyerrlab1
  370. /* Like YYERROR except do call yyerror.
  371.    This remains here temporarily to ease the
  372.    transition to the new meaning of YYERROR, for GCC.
  373.    Once GCC version 2 has supplanted version 1, this can go.  */
  374. #define YYFAIL        goto yyerrlab
  375. #define YYRECOVERING()  (!!yyerrstatus)
  376. #define YYBACKUP(token, value) \
  377. do                                \
  378.   if (yychar == YYEMPTY && yylen == 1)                \
  379.     { yychar = (token), yylval = (value);            \
  380.       yychar1 = YYTRANSLATE (yychar);                \
  381.       YYPOPSTACK;                        \
  382.       goto yybackup;                        \
  383.     }                                \
  384.   else                                \
  385.     { yyerror ("syntax error: cannot back up"); YYERROR; }    \
  386. while (0)
  387.  
  388. #define YYTERROR    1
  389. #define YYERRCODE    256
  390.  
  391. #ifndef YYPURE
  392. #define YYLEX        yylex()
  393. #endif
  394.  
  395. #ifdef YYPURE
  396. #ifdef YYLSP_NEEDED
  397. #define YYLEX        yylex(&yylval, &yylloc)
  398. #else
  399. #define YYLEX        yylex(&yylval)
  400. #endif
  401. #endif
  402.  
  403. /* If nonreentrant, generate the variables here */
  404.  
  405. #ifndef YYPURE
  406.  
  407. int    yychar;            /*  the lookahead symbol        */
  408. YYSTYPE    yylval;            /*  the semantic value of the        */
  409.                 /*  lookahead symbol            */
  410.  
  411. #ifdef YYLSP_NEEDED
  412. YYLTYPE yylloc;            /*  location data for the lookahead    */
  413.                 /*  symbol                */
  414. #endif
  415.  
  416. int yynerrs;            /*  number of parse errors so far       */
  417. #endif  /* not YYPURE */
  418.  
  419. #if YYDEBUG != 0
  420. int yydebug;            /*  nonzero means print parse trace    */
  421. /* Since this is uninitialized, it does not stop multiple parsers
  422.    from coexisting.  */
  423. #endif
  424.  
  425. /*  YYINITDEPTH indicates the initial size of the parser's stacks    */
  426.  
  427. #ifndef    YYINITDEPTH
  428. #define YYINITDEPTH 200
  429. #endif
  430.  
  431. /*  YYMAXDEPTH is the maximum size the stacks can grow to
  432.     (effective only if the built-in stack extension method is used).  */
  433.  
  434. #if YYMAXDEPTH == 0
  435. #undef YYMAXDEPTH
  436. #endif
  437.  
  438. #ifndef YYMAXDEPTH
  439. #define YYMAXDEPTH 10000
  440. #endif
  441.  
  442. #if __GNUC__ > 1        /* GNU C and GNU C++ define this.  */
  443. #define __yy_bcopy(FROM,TO,COUNT)    __builtin_memcpy(TO,FROM,COUNT)
  444. #else                /* not GNU C or C++ */
  445. #ifndef __cplusplus
  446.  
  447. /* This is the most reliable way to avoid incompatibilities
  448.    in available built-in functions on various systems.  */
  449. static void
  450. __yy_bcopy (from, to, count)
  451.      char *from;
  452.      char *to;
  453.      int count;
  454. {
  455.   register char *f = from;
  456.   register char *t = to;
  457.   register int i = count;
  458.  
  459.   while (i-- > 0)
  460.     *t++ = *f++;
  461. }
  462.  
  463. #else /* __cplusplus */
  464.  
  465. /* This is the most reliable way to avoid incompatibilities
  466.    in available built-in functions on various systems.  */
  467. static void
  468. __yy_bcopy (char *from, char *to, int count)
  469. {
  470.   register char *f = from;
  471.   register char *t = to;
  472.   register int i = count;
  473.  
  474.   while (i-- > 0)
  475.     *t++ = *f++;
  476. }
  477.  
  478. #endif
  479. #endif
  480.  
  481. #line 169 "/usr/local/lib/bison.simple"
  482. int
  483. yyparse()
  484. {
  485.   register int yystate;
  486.   register int yyn;
  487.   register short *yyssp;
  488.   register YYSTYPE *yyvsp;
  489.   int yyerrstatus;    /*  number of tokens to shift before error messages enabled */
  490.   int yychar1;        /*  lookahead token as an internal (translated) token number */
  491.  
  492.   short    yyssa[YYINITDEPTH];    /*  the state stack            */
  493.   YYSTYPE yyvsa[YYINITDEPTH];    /*  the semantic value stack        */
  494.  
  495.   short *yyss = yyssa;        /*  refer to the stacks thru separate pointers */
  496.   YYSTYPE *yyvs = yyvsa;    /*  to allow yyoverflow to reallocate them elsewhere */
  497.  
  498. #ifdef YYLSP_NEEDED
  499.   YYLTYPE yylsa[YYINITDEPTH];    /*  the location stack            */
  500.   YYLTYPE *yyls = yylsa;
  501.   YYLTYPE *yylsp;
  502.  
  503. #define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
  504. #else
  505. #define YYPOPSTACK   (yyvsp--, yyssp--)
  506. #endif
  507.  
  508.   int yystacksize = YYINITDEPTH;
  509.  
  510. #ifdef YYPURE
  511.   int yychar;
  512.   YYSTYPE yylval;
  513.   int yynerrs;
  514. #ifdef YYLSP_NEEDED
  515.   YYLTYPE yylloc;
  516. #endif
  517. #endif
  518.  
  519.   YYSTYPE yyval;        /*  the variable used to return        */
  520.                 /*  semantic values from the action    */
  521.                 /*  routines                */
  522.  
  523.   int yylen;
  524.  
  525. #if YYDEBUG != 0
  526.   if (yydebug)
  527.     fprintf(stderr, "Starting parse\n");
  528. #endif
  529.  
  530.   yystate = 0;
  531.   yyerrstatus = 0;
  532.   yynerrs = 0;
  533.   yychar = YYEMPTY;        /* Cause a token to be read.  */
  534.  
  535.   /* Initialize stack pointers.
  536.      Waste one element of value and location stack
  537.      so that they stay on the same level as the state stack.  */
  538.  
  539.   yyssp = yyss - 1;
  540.   yyvsp = yyvs;
  541. #ifdef YYLSP_NEEDED
  542.   yylsp = yyls;
  543. #endif
  544.  
  545. /* Push a new state, which is found in  yystate  .  */
  546. /* In all cases, when you get here, the value and location stacks
  547.    have just been pushed. so pushing a state here evens the stacks.  */
  548. yynewstate:
  549.  
  550.   *++yyssp = yystate;
  551.  
  552.   if (yyssp >= yyss + yystacksize - 1)
  553.     {
  554.       /* Give user a chance to reallocate the stack */
  555.       /* Use copies of these so that the &'s don't force the real ones into memory. */
  556.       YYSTYPE *yyvs1 = yyvs;
  557.       short *yyss1 = yyss;
  558. #ifdef YYLSP_NEEDED
  559.       YYLTYPE *yyls1 = yyls;
  560. #endif
  561.  
  562.       /* Get the current used size of the three stacks, in elements.  */
  563.       int size = yyssp - yyss + 1;
  564.  
  565. #ifdef yyoverflow
  566.       /* Each stack pointer address is followed by the size of
  567.      the data in use in that stack, in bytes.  */
  568.       yyoverflow("parser stack overflow",
  569.          &yyss1, size * sizeof (*yyssp),
  570.          &yyvs1, size * sizeof (*yyvsp),
  571. #ifdef YYLSP_NEEDED
  572.          &yyls1, size * sizeof (*yylsp),
  573. #endif
  574.          &yystacksize);
  575.  
  576.       yyss = yyss1; yyvs = yyvs1;
  577. #ifdef YYLSP_NEEDED
  578.       yyls = yyls1;
  579. #endif
  580. #else /* no yyoverflow */
  581.       /* Extend the stack our own way.  */
  582.       if (yystacksize >= YYMAXDEPTH)
  583.     {
  584.       yyerror("parser stack overflow");
  585.       return 2;
  586.     }
  587.       yystacksize *= 2;
  588.       if (yystacksize > YYMAXDEPTH)
  589.     yystacksize = YYMAXDEPTH;
  590.       yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
  591.       __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
  592.       yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
  593.       __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
  594. #ifdef YYLSP_NEEDED
  595.       yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
  596.       __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
  597. #endif
  598. #endif /* no yyoverflow */
  599.  
  600.       yyssp = yyss + size - 1;
  601.       yyvsp = yyvs + size - 1;
  602. #ifdef YYLSP_NEEDED
  603.       yylsp = yyls + size - 1;
  604. #endif
  605.  
  606. #if YYDEBUG != 0
  607.       if (yydebug)
  608.     fprintf(stderr, "Stack size increased to %d\n", yystacksize);
  609. #endif
  610.  
  611.       if (yyssp >= yyss + yystacksize - 1)
  612.     YYABORT;
  613.     }
  614.  
  615. #if YYDEBUG != 0
  616.   if (yydebug)
  617.     fprintf(stderr, "Entering state %d\n", yystate);
  618. #endif
  619.  
  620.  yybackup:
  621.  
  622. /* Do appropriate processing given the current state.  */
  623. /* Read a lookahead token if we need one and don't already have one.  */
  624. /* yyresume: */
  625.  
  626.   /* First try to decide what to do without reference to lookahead token.  */
  627.  
  628.   yyn = yypact[yystate];
  629.   if (yyn == YYFLAG)
  630.     goto yydefault;
  631.  
  632.   /* Not known => get a lookahead token if don't already have one.  */
  633.  
  634.   /* yychar is either YYEMPTY or YYEOF
  635.      or a valid token in external form.  */
  636.  
  637.   if (yychar == YYEMPTY)
  638.     {
  639. #if YYDEBUG != 0
  640.       if (yydebug)
  641.     fprintf(stderr, "Reading a token: ");
  642. #endif
  643.       yychar = YYLEX;
  644.     }
  645.  
  646.   /* Convert token to internal form (in yychar1) for indexing tables with */
  647.  
  648.   if (yychar <= 0)        /* This means end of input. */
  649.     {
  650.       yychar1 = 0;
  651.       yychar = YYEOF;        /* Don't call YYLEX any more */
  652.  
  653. #if YYDEBUG != 0
  654.       if (yydebug)
  655.     fprintf(stderr, "Now at end of input.\n");
  656. #endif
  657.     }
  658.   else
  659.     {
  660.       yychar1 = YYTRANSLATE(yychar);
  661.  
  662. #if YYDEBUG != 0
  663.       if (yydebug)
  664.     {
  665.       fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
  666.       /* Give the individual parser a way to print the precise meaning
  667.          of a token, for further debugging info.  */
  668. #ifdef YYPRINT
  669.       YYPRINT (stderr, yychar, yylval);
  670. #endif
  671.       fprintf (stderr, ")\n");
  672.     }
  673. #endif
  674.     }
  675.  
  676.   yyn += yychar1;
  677.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
  678.     goto yydefault;
  679.  
  680.   yyn = yytable[yyn];
  681.  
  682.   /* yyn is what to do for this token type in this state.
  683.      Negative => reduce, -yyn is rule number.
  684.      Positive => shift, yyn is new state.
  685.        New state is final state => don't bother to shift,
  686.        just return success.
  687.      0, or most negative number => error.  */
  688.  
  689.   if (yyn < 0)
  690.     {
  691.       if (yyn == YYFLAG)
  692.     goto yyerrlab;
  693.       yyn = -yyn;
  694.       goto yyreduce;
  695.     }
  696.   else if (yyn == 0)
  697.     goto yyerrlab;
  698.  
  699.   if (yyn == YYFINAL)
  700.     YYACCEPT;
  701.  
  702.   /* Shift the lookahead token.  */
  703.  
  704. #if YYDEBUG != 0
  705.   if (yydebug)
  706.     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
  707. #endif
  708.  
  709.   /* Discard the token being shifted unless it is eof.  */
  710.   if (yychar != YYEOF)
  711.     yychar = YYEMPTY;
  712.  
  713.   *++yyvsp = yylval;
  714. #ifdef YYLSP_NEEDED
  715.   *++yylsp = yylloc;
  716. #endif
  717.  
  718.   /* count tokens shifted since error; after three, turn off error status.  */
  719.   if (yyerrstatus) yyerrstatus--;
  720.  
  721.   yystate = yyn;
  722.   goto yynewstate;
  723.  
  724. /* Do the default action for the current state.  */
  725. yydefault:
  726.  
  727.   yyn = yydefact[yystate];
  728.   if (yyn == 0)
  729.     goto yyerrlab;
  730.  
  731. /* Do a reduction.  yyn is the number of a rule to reduce with.  */
  732. yyreduce:
  733.   yylen = yyr2[yyn];
  734.   yyval = yyvsp[1-yylen]; /* implement default value of the action */
  735.  
  736. #if YYDEBUG != 0
  737.   if (yydebug)
  738.     {
  739.       int i;
  740.  
  741.       fprintf (stderr, "Reducing via rule %d (line %d), ",
  742.            yyn, yyrline[yyn]);
  743.  
  744.       /* Print the symboles being reduced, and their result.  */
  745.       for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
  746.     fprintf (stderr, "%s ", yytname[yyrhs[i]]);
  747.       fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
  748.     }
  749. #endif
  750.  
  751.  
  752.   switch (yyn) {
  753.  
  754. case 3:
  755. #line 153 "getdate.y"
  756. {
  757.         yyHaveTime++;
  758.     ;
  759.     break;}
  760. case 4:
  761. #line 156 "getdate.y"
  762. {
  763.         yyHaveZone++;
  764.     ;
  765.     break;}
  766. case 5:
  767. #line 159 "getdate.y"
  768. {
  769.         yyHaveDate++;
  770.     ;
  771.     break;}
  772. case 6:
  773. #line 162 "getdate.y"
  774. {
  775.         yyHaveDay++;
  776.     ;
  777.     break;}
  778. case 7:
  779. #line 165 "getdate.y"
  780. {
  781.         yyHaveRel++;
  782.     ;
  783.     break;}
  784. case 9:
  785. #line 171 "getdate.y"
  786. {
  787.         yyHour = yyvsp[-1].Number;
  788.         yyMinutes = 0;
  789.         yySeconds = 0;
  790.         yyMeridian = yyvsp[0].Meridian;
  791.     ;
  792.     break;}
  793. case 10:
  794. #line 177 "getdate.y"
  795. {
  796.         yyHour = yyvsp[-3].Number;
  797.         yyMinutes = yyvsp[-1].Number;
  798.         yySeconds = 0;
  799.         yyMeridian = yyvsp[0].Meridian;
  800.     ;
  801.     break;}
  802. case 11:
  803. #line 183 "getdate.y"
  804. {
  805.         yyHour = yyvsp[-3].Number;
  806.         yyMinutes = yyvsp[-1].Number;
  807.         yyMeridian = MER24;
  808.         yyDSTmode = DSToff;
  809.         yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
  810.     ;
  811.     break;}
  812. case 12:
  813. #line 190 "getdate.y"
  814. {
  815.         yyHour = yyvsp[-5].Number;
  816.         yyMinutes = yyvsp[-3].Number;
  817.         yySeconds = yyvsp[-1].Number;
  818.         yyMeridian = yyvsp[0].Meridian;
  819.     ;
  820.     break;}
  821. case 13:
  822. #line 196 "getdate.y"
  823. {
  824.         yyHour = yyvsp[-5].Number;
  825.         yyMinutes = yyvsp[-3].Number;
  826.         yySeconds = yyvsp[-1].Number;
  827.         yyMeridian = MER24;
  828.         yyDSTmode = DSToff;
  829.         yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
  830.     ;
  831.     break;}
  832. case 14:
  833. #line 206 "getdate.y"
  834. {
  835.         yyTimezone = yyvsp[0].Number;
  836.         yyDSTmode = DSToff;
  837.     ;
  838.     break;}
  839. case 15:
  840. #line 210 "getdate.y"
  841. {
  842.         yyTimezone = yyvsp[0].Number;
  843.         yyDSTmode = DSTon;
  844.     ;
  845.     break;}
  846. case 16:
  847. #line 216 "getdate.y"
  848. {
  849.         yyDayOrdinal = 1;
  850.         yyDayNumber = yyvsp[0].Number;
  851.     ;
  852.     break;}
  853. case 17:
  854. #line 220 "getdate.y"
  855. {
  856.         yyDayOrdinal = 1;
  857.         yyDayNumber = yyvsp[-1].Number;
  858.     ;
  859.     break;}
  860. case 18:
  861. #line 224 "getdate.y"
  862. {
  863.         yyDayOrdinal = yyvsp[-1].Number;
  864.         yyDayNumber = yyvsp[0].Number;
  865.     ;
  866.     break;}
  867. case 19:
  868. #line 230 "getdate.y"
  869. {
  870.         yyMonth = yyvsp[-2].Number;
  871.         yyDay = yyvsp[0].Number;
  872.     ;
  873.     break;}
  874. case 20:
  875. #line 234 "getdate.y"
  876. {
  877.         yyMonth = yyvsp[-4].Number;
  878.         yyDay = yyvsp[-2].Number;
  879.         yyYear = yyvsp[0].Number;
  880.     ;
  881.     break;}
  882. case 21:
  883. #line 239 "getdate.y"
  884. {
  885.         yyMonth = yyvsp[-1].Number;
  886.         yyDay = yyvsp[0].Number;
  887.     ;
  888.     break;}
  889. case 22:
  890. #line 243 "getdate.y"
  891. {
  892.         yyMonth = yyvsp[-3].Number;
  893.         yyDay = yyvsp[-2].Number;
  894.         yyYear = yyvsp[0].Number;
  895.     ;
  896.     break;}
  897. case 23:
  898. #line 248 "getdate.y"
  899. {
  900.         yyMonth = yyvsp[0].Number;
  901.         yyDay = yyvsp[-1].Number;
  902.     ;
  903.     break;}
  904. case 24:
  905. #line 252 "getdate.y"
  906. {
  907.         yyMonth = yyvsp[-1].Number;
  908.         yyDay = yyvsp[-2].Number;
  909.         yyYear = yyvsp[0].Number;
  910.     ;
  911.     break;}
  912. case 25:
  913. #line 259 "getdate.y"
  914. {
  915.         yyRelSeconds = -yyRelSeconds;
  916.         yyRelMonth = -yyRelMonth;
  917.     ;
  918.     break;}
  919. case 27:
  920. #line 266 "getdate.y"
  921. {
  922.         yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
  923.     ;
  924.     break;}
  925. case 28:
  926. #line 269 "getdate.y"
  927. {
  928.         yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
  929.     ;
  930.     break;}
  931. case 29:
  932. #line 272 "getdate.y"
  933. {
  934.         yyRelSeconds += yyvsp[0].Number * 60L;
  935.     ;
  936.     break;}
  937. case 30:
  938. #line 275 "getdate.y"
  939. {
  940.         yyRelSeconds += yyvsp[-1].Number;
  941.     ;
  942.     break;}
  943. case 31:
  944. #line 278 "getdate.y"
  945. {
  946.         yyRelSeconds += yyvsp[-1].Number;
  947.     ;
  948.     break;}
  949. case 32:
  950. #line 281 "getdate.y"
  951. {
  952.         yyRelSeconds++;
  953.     ;
  954.     break;}
  955. case 33:
  956. #line 284 "getdate.y"
  957. {
  958.         yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
  959.     ;
  960.     break;}
  961. case 34:
  962. #line 287 "getdate.y"
  963. {
  964.         yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
  965.     ;
  966.     break;}
  967. case 35:
  968. #line 290 "getdate.y"
  969. {
  970.         yyRelMonth += yyvsp[0].Number;
  971.     ;
  972.     break;}
  973. case 36:
  974. #line 295 "getdate.y"
  975. {
  976.         if (yyHaveTime && yyHaveDate && !yyHaveRel)
  977.         yyYear = yyvsp[0].Number;
  978.         else {
  979.         if(yyvsp[0].Number>10000) {
  980.             time_t date_part;
  981.  
  982.             date_part= yyvsp[0].Number/10000;
  983.             yyHaveDate++;
  984.             yyDay= (date_part)%100;
  985.             yyMonth= (date_part/100)%100;
  986.             yyYear = date_part/10000;
  987.         } 
  988.             yyHaveTime++;
  989.         if (yyvsp[0].Number < 100) {
  990.             yyHour = yyvsp[0].Number;
  991.             yyMinutes = 0;
  992.         }
  993.         else {
  994.             yyHour = yyvsp[0].Number / 100;
  995.             yyMinutes = yyvsp[0].Number % 100;
  996.         }
  997.         yySeconds = 0;
  998.         yyMeridian = MER24;
  999.         }
  1000.     ;
  1001.     break;}
  1002. case 37:
  1003. #line 323 "getdate.y"
  1004. {
  1005.         yyval.Meridian = MER24;
  1006.     ;
  1007.     break;}
  1008. case 38:
  1009. #line 326 "getdate.y"
  1010. {
  1011.         yyval.Meridian = yyvsp[0].Meridian;
  1012.     ;
  1013.     break;}
  1014. }
  1015.    /* the action file gets copied in in place of this dollarsign */
  1016. #line 440 "/usr/local/lib/bison.simple"
  1017.  
  1018.   yyvsp -= yylen;
  1019.   yyssp -= yylen;
  1020. #ifdef YYLSP_NEEDED
  1021.   yylsp -= yylen;
  1022. #endif
  1023.  
  1024. #if YYDEBUG != 0
  1025.   if (yydebug)
  1026.     {
  1027.       short *ssp1 = yyss - 1;
  1028.       fprintf (stderr, "state stack now");
  1029.       while (ssp1 != yyssp)
  1030.     fprintf (stderr, " %d", *++ssp1);
  1031.       fprintf (stderr, "\n");
  1032.     }
  1033. #endif
  1034.  
  1035.   *++yyvsp = yyval;
  1036.  
  1037. #ifdef YYLSP_NEEDED
  1038.   yylsp++;
  1039.   if (yylen == 0)
  1040.     {
  1041.       yylsp->first_line = yylloc.first_line;
  1042.       yylsp->first_column = yylloc.first_column;
  1043.       yylsp->last_line = (yylsp-1)->last_line;
  1044.       yylsp->last_column = (yylsp-1)->last_column;
  1045.       yylsp->text = 0;
  1046.     }
  1047.   else
  1048.     {
  1049.       yylsp->last_line = (yylsp+yylen-1)->last_line;
  1050.       yylsp->last_column = (yylsp+yylen-1)->last_column;
  1051.     }
  1052. #endif
  1053.  
  1054.   /* Now "shift" the result of the reduction.
  1055.      Determine what state that goes to,
  1056.      based on the state we popped back to
  1057.      and the rule number reduced by.  */
  1058.  
  1059.   yyn = yyr1[yyn];
  1060.  
  1061.   yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
  1062.   if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
  1063.     yystate = yytable[yystate];
  1064.   else
  1065.     yystate = yydefgoto[yyn - YYNTBASE];
  1066.  
  1067.   goto yynewstate;
  1068.  
  1069. yyerrlab:   /* here on detecting error */
  1070.  
  1071.   if (! yyerrstatus)
  1072.     /* If not already recovering from an error, report this error.  */
  1073.     {
  1074.       ++yynerrs;
  1075.  
  1076. #ifdef YYERROR_VERBOSE
  1077.       yyn = yypact[yystate];
  1078.  
  1079.       if (yyn > YYFLAG && yyn < YYLAST)
  1080.     {
  1081.       int size = 0;
  1082.       char *msg;
  1083.       int x, count;
  1084.  
  1085.       count = 0;
  1086.       for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
  1087.         if (yycheck[x + yyn] == x)
  1088.           size += strlen(yytname[x]) + 15, count++;
  1089.       msg = (char *) malloc(size + 15);
  1090.       if (msg != 0)
  1091.         {
  1092.           strcpy(msg, "parse error");
  1093.  
  1094.           if (count < 5)
  1095.         {
  1096.           count = 0;
  1097.           for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
  1098.             if (yycheck[x + yyn] == x)
  1099.               {
  1100.             strcat(msg, count == 0 ? ", expecting `" : " or `");
  1101.             strcat(msg, yytname[x]);
  1102.             strcat(msg, "'");
  1103.             count++;
  1104.               }
  1105.         }
  1106.           yyerror(msg);
  1107.           free(msg);
  1108.         }
  1109.       else
  1110.         yyerror ("parse error; also virtual memory exceeded");
  1111.     }
  1112.       else
  1113. #endif /* YYERROR_VERBOSE */
  1114.     yyerror("parse error");
  1115.     }
  1116.  
  1117. yyerrlab1:   /* here on error raised explicitly by an action */
  1118.  
  1119.   if (yyerrstatus == 3)
  1120.     {
  1121.       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
  1122.  
  1123.       /* return failure if at end of input */
  1124.       if (yychar == YYEOF)
  1125.     YYABORT;
  1126.  
  1127. #if YYDEBUG != 0
  1128.       if (yydebug)
  1129.     fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
  1130. #endif
  1131.  
  1132.       yychar = YYEMPTY;
  1133.     }
  1134.  
  1135.   /* Else will try to reuse lookahead token
  1136.      after shifting the error token.  */
  1137.  
  1138.   yyerrstatus = 3;        /* Each real token shifted decrements this */
  1139.  
  1140.   goto yyerrhandle;
  1141.  
  1142. yyerrdefault:  /* current state does not do anything special for the error token. */
  1143.  
  1144. #if 0
  1145.   /* This is wrong; only states that explicitly want error tokens
  1146.      should shift them.  */
  1147.   yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
  1148.   if (yyn) goto yydefault;
  1149. #endif
  1150.  
  1151. yyerrpop:   /* pop the current state because it cannot handle the error token */
  1152.  
  1153.   if (yyssp == yyss) YYABORT;
  1154.   yyvsp--;
  1155.   yystate = *--yyssp;
  1156. #ifdef YYLSP_NEEDED
  1157.   yylsp--;
  1158. #endif
  1159.  
  1160. #if YYDEBUG != 0
  1161.   if (yydebug)
  1162.     {
  1163.       short *ssp1 = yyss - 1;
  1164.       fprintf (stderr, "Error: state stack now");
  1165.       while (ssp1 != yyssp)
  1166.     fprintf (stderr, " %d", *++ssp1);
  1167.       fprintf (stderr, "\n");
  1168.     }
  1169. #endif
  1170.  
  1171. yyerrhandle:
  1172.  
  1173.   yyn = yypact[yystate];
  1174.   if (yyn == YYFLAG)
  1175.     goto yyerrdefault;
  1176.  
  1177.   yyn += YYTERROR;
  1178.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
  1179.     goto yyerrdefault;
  1180.  
  1181.   yyn = yytable[yyn];
  1182.   if (yyn < 0)
  1183.     {
  1184.       if (yyn == YYFLAG)
  1185.     goto yyerrpop;
  1186.       yyn = -yyn;
  1187.       goto yyreduce;
  1188.     }
  1189.   else if (yyn == 0)
  1190.     goto yyerrpop;
  1191.  
  1192.   if (yyn == YYFINAL)
  1193.     YYACCEPT;
  1194.  
  1195. #if YYDEBUG != 0
  1196.   if (yydebug)
  1197.     fprintf(stderr, "Shifting error token, ");
  1198. #endif
  1199.  
  1200.   *++yyvsp = yylval;
  1201. #ifdef YYLSP_NEEDED
  1202.   *++yylsp = yylloc;
  1203. #endif
  1204.  
  1205.   yystate = yyn;
  1206.   goto yynewstate;
  1207. }
  1208. #line 331 "getdate.y"
  1209.  
  1210.  
  1211. /* Month and day table. */
  1212. static TABLE    MonthDayTable[] = {
  1213.     { "january",    tMONTH,  1 },
  1214.     { "february",    tMONTH,  2 },
  1215.     { "march",        tMONTH,  3 },
  1216.     { "april",        tMONTH,  4 },
  1217.     { "may",        tMONTH,  5 },
  1218.     { "june",        tMONTH,  6 },
  1219.     { "july",        tMONTH,  7 },
  1220.     { "august",        tMONTH,  8 },
  1221.     { "september",    tMONTH,  9 },
  1222.     { "sept",        tMONTH,  9 },
  1223.     { "october",    tMONTH, 10 },
  1224.     { "november",    tMONTH, 11 },
  1225.     { "december",    tMONTH, 12 },
  1226.     { "sunday",        tDAY, 0 },
  1227.     { "monday",        tDAY, 1 },
  1228.     { "tuesday",    tDAY, 2 },
  1229.     { "tues",        tDAY, 2 },
  1230.     { "wednesday",    tDAY, 3 },
  1231.     { "wednes",        tDAY, 3 },
  1232.     { "thursday",    tDAY, 4 },
  1233.     { "thur",        tDAY, 4 },
  1234.     { "thurs",        tDAY, 4 },
  1235.     { "friday",        tDAY, 5 },
  1236.     { "saturday",    tDAY, 6 },
  1237.     { NULL }
  1238. };
  1239.  
  1240. /* Time units table. */
  1241. static TABLE    UnitsTable[] = {
  1242.     { "year",        tMONTH_UNIT,    12 },
  1243.     { "month",        tMONTH_UNIT,    1 },
  1244.     { "fortnight",    tMINUTE_UNIT,    14 * 24 * 60 },
  1245.     { "week",        tMINUTE_UNIT,    7 * 24 * 60 },
  1246.     { "day",        tMINUTE_UNIT,    1 * 24 * 60 },
  1247.     { "hour",        tMINUTE_UNIT,    60 },
  1248.     { "minute",        tMINUTE_UNIT,    1 },
  1249.     { "min",        tMINUTE_UNIT,    1 },
  1250.     { "second",        tSEC_UNIT,    1 },
  1251.     { "sec",        tSEC_UNIT,    1 },
  1252.     { NULL }
  1253. };
  1254.  
  1255. /* Assorted relative-time words. */
  1256. static TABLE    OtherTable[] = {
  1257.     { "tomorrow",    tMINUTE_UNIT,    1 * 24 * 60 },
  1258.     { "yesterday",    tMINUTE_UNIT,    -1 * 24 * 60 },
  1259.     { "today",        tMINUTE_UNIT,    0 },
  1260.     { "now",        tMINUTE_UNIT,    0 },
  1261.     { "last",        tUNUMBER,    -1 },
  1262.     { "this",        tMINUTE_UNIT,    0 },
  1263.     { "next",        tUNUMBER,    2 },
  1264.     { "first",        tUNUMBER,    1 },
  1265. /*  { "second",        tUNUMBER,    2 }, */
  1266.     { "third",        tUNUMBER,    3 },
  1267.     { "fourth",        tUNUMBER,    4 },
  1268.     { "fifth",        tUNUMBER,    5 },
  1269.     { "sixth",        tUNUMBER,    6 },
  1270.     { "seventh",    tUNUMBER,    7 },
  1271.     { "eighth",        tUNUMBER,    8 },
  1272.     { "ninth",        tUNUMBER,    9 },
  1273.     { "tenth",        tUNUMBER,    10 },
  1274.     { "eleventh",    tUNUMBER,    11 },
  1275.     { "twelfth",    tUNUMBER,    12 },
  1276.     { "ago",        tAGO,    1 },
  1277.     { NULL }
  1278. };
  1279.  
  1280. /* The timezone table. */
  1281. static TABLE    TimezoneTable[] = {
  1282.     { "gmt",    tZONE,     HOUR( 0) },    /* Greenwich Mean */
  1283.     { "ut",    tZONE,     HOUR( 0) },    /* Universal (Coordinated) */
  1284.     { "utc",    tZONE,     HOUR( 0) },
  1285.     { "wet",    tZONE,     HOUR( 0) },    /* Western European */
  1286.     { "bst",    tDAYZONE,  HOUR( 0) },    /* British Summer */
  1287.     { "wat",    tZONE,     HOUR( 1) },    /* West Africa */
  1288.     { "at",    tZONE,     HOUR( 2) },    /* Azores */
  1289. #if    0
  1290.     /* For completeness.  BST is also British Summer, and GST is
  1291.      * also Guam Standard. */
  1292.     { "bst",    tZONE,     HOUR( 3) },    /* Brazil Standard */
  1293.     { "gst",    tZONE,     HOUR( 3) },    /* Greenland Standard */
  1294. #endif
  1295.     { "nft",    tZONE,     HOUR(3.5) },    /* Newfoundland */
  1296.     { "nst",    tZONE,     HOUR(3.5) },    /* Newfoundland Standard */
  1297.     { "ndt",    tDAYZONE,  HOUR(3.5) },    /* Newfoundland Daylight */
  1298.     { "ast",    tZONE,     HOUR( 4) },    /* Atlantic Standard */
  1299.     { "adt",    tDAYZONE,  HOUR( 4) },    /* Atlantic Daylight */
  1300.     { "est",    tZONE,     HOUR( 5) },    /* Eastern Standard */
  1301.     { "edt",    tDAYZONE,  HOUR( 5) },    /* Eastern Daylight */
  1302.     { "cst",    tZONE,     HOUR( 6) },    /* Central Standard */
  1303.     { "cdt",    tDAYZONE,  HOUR( 6) },    /* Central Daylight */
  1304.     { "mst",    tZONE,     HOUR( 7) },    /* Mountain Standard */
  1305.     { "mdt",    tDAYZONE,  HOUR( 7) },    /* Mountain Daylight */
  1306.     { "pst",    tZONE,     HOUR( 8) },    /* Pacific Standard */
  1307.     { "pdt",    tDAYZONE,  HOUR( 8) },    /* Pacific Daylight */
  1308.     { "yst",    tZONE,     HOUR( 9) },    /* Yukon Standard */
  1309.     { "ydt",    tDAYZONE,  HOUR( 9) },    /* Yukon Daylight */
  1310.     { "hst",    tZONE,     HOUR(10) },    /* Hawaii Standard */
  1311.     { "hdt",    tDAYZONE,  HOUR(10) },    /* Hawaii Daylight */
  1312.     { "cat",    tZONE,     HOUR(10) },    /* Central Alaska */
  1313.     { "ahst",    tZONE,     HOUR(10) },    /* Alaska-Hawaii Standard */
  1314.     { "nt",    tZONE,     HOUR(11) },    /* Nome */
  1315.     { "idlw",    tZONE,     HOUR(12) },    /* International Date Line West */
  1316.     { "cet",    tZONE,     -HOUR(1) },    /* Central European */
  1317.     { "met",    tZONE,     -HOUR(1) },    /* Middle European */
  1318.     { "mewt",    tZONE,     -HOUR(1) },    /* Middle European Winter */
  1319.     { "mest",    tDAYZONE,  -HOUR(1) },    /* Middle European Summer */
  1320.     { "swt",    tZONE,     -HOUR(1) },    /* Swedish Winter */
  1321.     { "sst",    tDAYZONE,  -HOUR(1) },    /* Swedish Summer */
  1322.     { "fwt",    tZONE,     -HOUR(1) },    /* French Winter */
  1323.     { "fst",    tDAYZONE,  -HOUR(1) },    /* French Summer */
  1324.     { "eet",    tZONE,     -HOUR(2) },    /* Eastern Europe, USSR Zone 1 */
  1325.     { "bt",    tZONE,     -HOUR(3) },    /* Baghdad, USSR Zone 2 */
  1326.     { "it",    tZONE,     -HOUR(3.5) },/* Iran */
  1327.     { "zp4",    tZONE,     -HOUR(4) },    /* USSR Zone 3 */
  1328.     { "zp5",    tZONE,     -HOUR(5) },    /* USSR Zone 4 */
  1329.     { "ist",    tZONE,     -HOUR(5.5) },/* Indian Standard */
  1330.     { "zp6",    tZONE,     -HOUR(6) },    /* USSR Zone 5 */
  1331. #if    0
  1332.     /* For completeness.  NST is also Newfoundland Stanard, nad SST is
  1333.      * also Swedish Summer. */
  1334.     { "nst",    tZONE,     -HOUR(6.5) },/* North Sumatra */
  1335.     { "sst",    tZONE,     -HOUR(7) },    /* South Sumatra, USSR Zone 6 */
  1336. #endif    /* 0 */
  1337.     { "wast",    tZONE,     -HOUR(7) },    /* West Australian Standard */
  1338.     { "wadt",    tDAYZONE,  -HOUR(7) },    /* West Australian Daylight */
  1339.     { "jt",    tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
  1340.     { "cct",    tZONE,     -HOUR(8) },    /* China Coast, USSR Zone 7 */
  1341.     { "jst",    tZONE,     -HOUR(9) },    /* Japan Standard, USSR Zone 8 */
  1342.     { "cast",    tZONE,     -HOUR(9.5) },/* Central Australian Standard */
  1343.     { "cadt",    tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
  1344.     { "east",    tZONE,     -HOUR(10) },    /* Eastern Australian Standard */
  1345.     { "eadt",    tDAYZONE,  -HOUR(10) },    /* Eastern Australian Daylight */
  1346.     { "gst",    tZONE,     -HOUR(10) },    /* Guam Standard, USSR Zone 9 */
  1347.     { "nzt",    tZONE,     -HOUR(12) },    /* New Zealand */
  1348.     { "nzst",    tZONE,     -HOUR(12) },    /* New Zealand Standard */
  1349.     { "nzdt",    tDAYZONE,  -HOUR(12) },    /* New Zealand Daylight */
  1350.     { "idle",    tZONE,     -HOUR(12) },    /* International Date Line East */
  1351.     {  NULL  }
  1352. };
  1353.  
  1354. /* Military timezone table. */
  1355. static TABLE    MilitaryTable[] = {
  1356.     { "a",    tZONE,    HOUR(  1) },
  1357.     { "b",    tZONE,    HOUR(  2) },
  1358.     { "c",    tZONE,    HOUR(  3) },
  1359.     { "d",    tZONE,    HOUR(  4) },
  1360.     { "e",    tZONE,    HOUR(  5) },
  1361.     { "f",    tZONE,    HOUR(  6) },
  1362.     { "g",    tZONE,    HOUR(  7) },
  1363.     { "h",    tZONE,    HOUR(  8) },
  1364.     { "i",    tZONE,    HOUR(  9) },
  1365.     { "k",    tZONE,    HOUR( 10) },
  1366.     { "l",    tZONE,    HOUR( 11) },
  1367.     { "m",    tZONE,    HOUR( 12) },
  1368.     { "n",    tZONE,    HOUR(- 1) },
  1369.     { "o",    tZONE,    HOUR(- 2) },
  1370.     { "p",    tZONE,    HOUR(- 3) },
  1371.     { "q",    tZONE,    HOUR(- 4) },
  1372.     { "r",    tZONE,    HOUR(- 5) },
  1373.     { "s",    tZONE,    HOUR(- 6) },
  1374.     { "t",    tZONE,    HOUR(- 7) },
  1375.     { "u",    tZONE,    HOUR(- 8) },
  1376.     { "v",    tZONE,    HOUR(- 9) },
  1377.     { "w",    tZONE,    HOUR(-10) },
  1378.     { "x",    tZONE,    HOUR(-11) },
  1379.     { "y",    tZONE,    HOUR(-12) },
  1380.     { "z",    tZONE,    HOUR(  0) },
  1381.     { NULL }
  1382. };
  1383.  
  1384.  
  1385.  
  1386.  
  1387. /* ARGSUSED */
  1388. int
  1389. yyerror(s)
  1390.     char    *s;
  1391. {
  1392.   return 0;
  1393. }
  1394.  
  1395.  
  1396. static time_t
  1397. ToSeconds(Hours, Minutes, Seconds, Meridian)
  1398.     time_t    Hours;
  1399.     time_t    Minutes;
  1400.     time_t    Seconds;
  1401.     MERIDIAN    Meridian;
  1402. {
  1403.     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
  1404.     return -1;
  1405.     switch (Meridian) {
  1406.     case MER24:
  1407.     if (Hours < 0 || Hours > 23)
  1408.         return -1;
  1409.     return (Hours * 60L + Minutes) * 60L + Seconds;
  1410.     case MERam:
  1411.     if (Hours < 1 || Hours > 12)
  1412.         return -1;
  1413.     return (Hours * 60L + Minutes) * 60L + Seconds;
  1414.     case MERpm:
  1415.     if (Hours < 1 || Hours > 12)
  1416.         return -1;
  1417.     return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
  1418.     }
  1419.     /* NOTREACHED */
  1420. }
  1421.  
  1422.  
  1423. static time_t
  1424. Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
  1425.     time_t    Month;
  1426.     time_t    Day;
  1427.     time_t    Year;
  1428.     time_t    Hours;
  1429.     time_t    Minutes;
  1430.     time_t    Seconds;
  1431.     MERIDIAN    Meridian;
  1432.     DSTMODE    DSTmode;
  1433. {
  1434.     static int    DaysInMonth[12] = {
  1435.     31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  1436.     };
  1437.     time_t    tod;
  1438.     time_t    Julian;
  1439.     int        i;
  1440.  
  1441.     if (Year < 0)
  1442.     Year = -Year;
  1443.     if (Year < 100)
  1444.     Year += 1900;
  1445.     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
  1446.             ? 29 : 28;
  1447.     if (Year < EPOCH || Year > 1999
  1448.      || Month < 1 || Month > 12
  1449.      /* Lint fluff:  "conversion from long may lose accuracy" */
  1450.      || Day < 1 || Day > DaysInMonth[(int)--Month])
  1451.     return -1;
  1452.  
  1453.     for (Julian = Day - 1, i = 0; i < Month; i++)
  1454.     Julian += DaysInMonth[i];
  1455.     for (i = EPOCH; i < Year; i++)
  1456.     Julian += 365 + (i % 4 == 0);
  1457.     Julian *= SECSPERDAY;
  1458.     Julian += yyTimezone * 60L;
  1459.     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
  1460.     return -1;
  1461.     Julian += tod;
  1462.     if (DSTmode == DSTon
  1463.      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
  1464.     Julian -= 60 * 60;
  1465.     return Julian;
  1466. }
  1467.  
  1468.  
  1469. static time_t
  1470. DSTcorrect(Start, Future)
  1471.     time_t    Start;
  1472.     time_t    Future;
  1473. {
  1474.     time_t    StartDay;
  1475.     time_t    FutureDay;
  1476.  
  1477.     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
  1478.     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
  1479.     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
  1480. }
  1481.  
  1482.  
  1483. static time_t
  1484. RelativeDate(Start, DayOrdinal, DayNumber)
  1485.     time_t    Start;
  1486.     time_t    DayOrdinal;
  1487.     time_t    DayNumber;
  1488. {
  1489.     struct tm    *tm;
  1490.     time_t    now;
  1491.  
  1492.     now = Start;
  1493.     tm = localtime(&now);
  1494.     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
  1495.     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
  1496.     return DSTcorrect(Start, now);
  1497. }
  1498.  
  1499.  
  1500. static time_t
  1501. RelativeMonth(Start, RelMonth)
  1502.     time_t    Start;
  1503.     time_t    RelMonth;
  1504. {
  1505.     struct tm    *tm;
  1506.     time_t    Month;
  1507.     time_t    Year;
  1508.  
  1509.     if (RelMonth == 0)
  1510.     return 0;
  1511.     tm = localtime(&Start);
  1512.     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
  1513.     Year = Month / 12;
  1514.     Month = Month % 12 + 1;
  1515.     return DSTcorrect(Start,
  1516.         Convert(Month, (time_t)tm->tm_mday, Year,
  1517.         (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
  1518.         MER24, DSTmaybe));
  1519. }
  1520.  
  1521.  
  1522. static int
  1523. LookupWord(buff)
  1524.     char        *buff;
  1525. {
  1526.     register char    *p;
  1527.     register char    *q;
  1528.     register TABLE    *tp;
  1529.     int            i;
  1530.     int            abbrev;
  1531.  
  1532.     /* Make it lowercase. */
  1533.     for (p = buff; *p; p++)
  1534.     if (isupper(*p))
  1535.         *p = tolower(*p);
  1536.  
  1537.     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
  1538.     yylval.Meridian = MERam;
  1539.     return tMERIDIAN;
  1540.     }
  1541.     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
  1542.     yylval.Meridian = MERpm;
  1543.     return tMERIDIAN;
  1544.     }
  1545.  
  1546.     /* See if we have an abbreviation for a month. */
  1547.     if (strlen(buff) == 3)
  1548.     abbrev = 1;
  1549.     else if (strlen(buff) == 4 && buff[3] == '.') {
  1550.     abbrev = 1;
  1551.     buff[3] = '\0';
  1552.     }
  1553.     else
  1554.     abbrev = 0;
  1555.  
  1556.     for (tp = MonthDayTable; tp->name; tp++) {
  1557.     if (abbrev) {
  1558.         if (strncmp(buff, tp->name, 3) == 0) {
  1559.         yylval.Number = tp->value;
  1560.         return tp->type;
  1561.         }
  1562.     }
  1563.     else if (strcmp(buff, tp->name) == 0) {
  1564.         yylval.Number = tp->value;
  1565.         return tp->type;
  1566.     }
  1567.     }
  1568.  
  1569.     for (tp = TimezoneTable; tp->name; tp++)
  1570.     if (strcmp(buff, tp->name) == 0) {
  1571.         yylval.Number = tp->value;
  1572.         return tp->type;
  1573.     }
  1574.  
  1575.     for (tp = UnitsTable; tp->name; tp++)
  1576.     if (strcmp(buff, tp->name) == 0) {
  1577.         yylval.Number = tp->value;
  1578.         return tp->type;
  1579.     }
  1580.  
  1581.     /* Strip off any plural and try the units table again. */
  1582.     i = strlen(buff) - 1;
  1583.     if (buff[i] == 's') {
  1584.     buff[i] = '\0';
  1585.     for (tp = UnitsTable; tp->name; tp++)
  1586.         if (strcmp(buff, tp->name) == 0) {
  1587.         yylval.Number = tp->value;
  1588.         return tp->type;
  1589.         }
  1590.     buff[i] = 's';        /* Put back for "this" in OtherTable. */
  1591.     }
  1592.  
  1593.     for (tp = OtherTable; tp->name; tp++)
  1594.     if (strcmp(buff, tp->name) == 0) {
  1595.         yylval.Number = tp->value;
  1596.         return tp->type;
  1597.     }
  1598.  
  1599.     /* Military timezones. */
  1600.     if (buff[1] == '\0' && isalpha(*buff)) {
  1601.     for (tp = MilitaryTable; tp->name; tp++)
  1602.         if (strcmp(buff, tp->name) == 0) {
  1603.         yylval.Number = tp->value;
  1604.         return tp->type;
  1605.         }
  1606.     }
  1607.  
  1608.     /* Drop out any periods and try the timezone table again. */
  1609.     for (i = 0, p = q = buff; *q; q++)
  1610.     if (*q != '.')
  1611.         *p++ = *q;
  1612.     else
  1613.         i++;
  1614.     *p = '\0';
  1615.     if (i)
  1616.     for (tp = TimezoneTable; tp->name; tp++)
  1617.         if (strcmp(buff, tp->name) == 0) {
  1618.         yylval.Number = tp->value;
  1619.         return tp->type;
  1620.         }
  1621.  
  1622.     return tID;
  1623. }
  1624.  
  1625.  
  1626. int
  1627. yylex()
  1628. {
  1629.     register char    c;
  1630.     register char    *p;
  1631.     char        buff[20];
  1632.     int            Count;
  1633.     int            sign;
  1634.  
  1635.     for ( ; ; ) {
  1636.     while (isspace(*yyInput))
  1637.         yyInput++;
  1638.  
  1639.     if (isdigit(c = *yyInput) || c == '-' || c == '+') {
  1640.         if (c == '-' || c == '+') {
  1641.         sign = c == '-' ? -1 : 1;
  1642.         if (!isdigit(*++yyInput))
  1643.             /* skip the '-' sign */
  1644.             continue;
  1645.         }
  1646.         else
  1647.         sign = 0;
  1648.         for (yylval.Number = 0; isdigit(c = *yyInput++); )
  1649.         yylval.Number = 10 * yylval.Number + c - '0';
  1650.         yyInput--;
  1651.         if (sign < 0)
  1652.         yylval.Number = -yylval.Number;
  1653.         return sign ? tSNUMBER : tUNUMBER;
  1654.     }
  1655.     if (isalpha(c)) {
  1656.         for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
  1657.         if (p < &buff[sizeof buff - 1])
  1658.             *p++ = c;
  1659.         *p = '\0';
  1660.         yyInput--;
  1661.         return LookupWord(buff);
  1662.     }
  1663.     if (c != '(')
  1664.         return *yyInput++;
  1665.     Count = 0;
  1666.     do {
  1667.         c = *yyInput++;
  1668.         if (c == '\0')
  1669.         return c;
  1670.         if (c == '(')
  1671.         Count++;
  1672.         else if (c == ')')
  1673.         Count--;
  1674.     } while (Count > 0);
  1675.     }
  1676. }
  1677.  
  1678.  
  1679. time_t
  1680. get_date(p, now)
  1681.     char        *p;
  1682.     struct timeb    *now;
  1683. {
  1684.     struct tm        *tm;
  1685.     struct timeb    ftz;
  1686.     time_t        Start;
  1687.     time_t        tod;
  1688.  
  1689.     yyInput = p;
  1690.     if (now == NULL) {
  1691.     now = &ftz;
  1692. #if    defined(NEED_TZSET)
  1693.     (void)time(&ftz.time);
  1694.     /* Set the timezone global. */
  1695.     tzset();
  1696.     ftz.timezone = (int) timezone / 60;
  1697. #else
  1698.     (void)ftime(&ftz);
  1699. #endif    /* defined(NEED_TZSET) */
  1700.     }
  1701.  
  1702.     tm = localtime(&now->time);
  1703.     yyYear = tm->tm_year;
  1704.     yyMonth = tm->tm_mon + 1;
  1705.     yyDay = tm->tm_mday;
  1706.     yyTimezone = now->timezone;
  1707.     yyDSTmode = DSTmaybe;
  1708.     yyHour = 0;
  1709.     yyMinutes = 0;
  1710.     yySeconds = 0;
  1711.     yyMeridian = MER24;
  1712.     yyRelSeconds = 0;
  1713.     yyRelMonth = 0;
  1714.     yyHaveDate = 0;
  1715.     yyHaveDay = 0;
  1716.     yyHaveRel = 0;
  1717.     yyHaveTime = 0;
  1718.     yyHaveZone = 0;
  1719.  
  1720.     if (yyparse()
  1721.      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
  1722.     return -1;
  1723.  
  1724.     if (yyHaveDate || yyHaveTime || yyHaveDay) {
  1725.     Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
  1726.             yyMeridian, yyDSTmode);
  1727.     if (Start < 0)
  1728.         return -1;
  1729.     }
  1730.     else {
  1731.     Start = now->time;
  1732.     if (!yyHaveRel)
  1733.         Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
  1734.     }
  1735.  
  1736.     Start += yyRelSeconds;
  1737.     Start += RelativeMonth(Start, yyRelMonth);
  1738.  
  1739.     if (yyHaveDay && !yyHaveDate) {
  1740.     tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
  1741.     Start += tod;
  1742.     }
  1743.  
  1744.     /* Have to do *something* with a legitimate -1 so it's distinguishable
  1745.      * from the error return value.  (Alternately could set errno on error.) */
  1746.     return Start == -1 ? 0 : Start;
  1747. }
  1748.  
  1749.  
  1750. #if    defined(TEST)
  1751.  
  1752. /* ARGSUSED */
  1753. main(ac, av)
  1754.     int        ac;
  1755.     char    *av[];
  1756. {
  1757.     char    buff[128];
  1758.     time_t    d;
  1759.  
  1760.     (void)printf("Enter date, or blank line to exit.\n\t> ");
  1761.     (void)fflush(stdout);
  1762.     while (gets(buff) && buff[0]) {
  1763.     d = get_date(buff, (struct timeb *)NULL);
  1764.     if (d == -1)
  1765.         (void)printf("Bad format - couldn't convert.\n");
  1766.     else
  1767.         (void)printf("%s", ctime(&d));
  1768.     (void)printf("\t> ");
  1769.     (void)fflush(stdout);
  1770.     }
  1771.     exit(0);
  1772.     /* NOTREACHED */
  1773. }
  1774. #endif    /* defined(TEST) */
  1775.